Sys.setenv(LANG = "en")
library(listdown)
## Warning: package 'listdown' was built under R version 4.0.4
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.0.4
library(gtsummary)
## Warning: package 'gtsummary' was built under R version 4.0.4
library(flextable)
## Warning: package 'flextable' was built under R version 4.0.5
## 
## Attaching package: 'flextable'
## The following object is masked from 'package:gtsummary':
## 
##     as_flextable
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.0.4
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(survival)
library(survminer)
## Warning: package 'survminer' was built under R version 4.0.4
## Loading required package: ggpubr
## Warning: package 'ggpubr' was built under R version 4.0.4
## 
## Attaching package: 'ggpubr'
## The following objects are masked from 'package:flextable':
## 
##     border, font, rotate
library(rmarkdown)
library(plotly)
## Warning: package 'plotly' was built under R version 4.0.4
## 
## Attaching package: 'plotly'
## The following objects are masked from 'package:flextable':
## 
##     highlight, style
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
library(gapminder)
## Warning: package 'gapminder' was built under R version 4.0.4
library(trelliscopejs)
## Warning: package 'trelliscopejs' was built under R version 4.0.4
library(DT)
## Warning: package 'DT' was built under R version 4.0.4
library(knitr)
## Warning: package 'knitr' was built under R version 4.0.4

Abstract

Statisticians and analysts have been using R for a long time. R programming environment has reproducible document standards embedded, such as R markdown. While R markdown requires the programmer to manually construct the structure of reproducible file, R list-down Package provides a programmatic solution to generate the files. On top of the already available R list down package, this paper demonstrates implanting graphs and interactive plots when users generate any reproducible documents by using trelliscopejs package. The concept is followed by a demonstration using gapminder dataset.

The R markdown (Baumer, Cetinkaya-Rundel, Bray, Loi, and Horton, 2014) demonstrates the possibility of constructing reproducible documents using R language. The format allows author to integrate R codes, written work, data tables, visualization plots and much more information into one directly structured document. Amongst scientific writings and analytical reports knitted using R markdown, the majority are made up of codes and narrative writings. The codes are usually but not limited to common computing languages, such as R, Python, SQL and others. The writings which contextualize the codes usually follow the codes. Sometimes writings are also placed between the codes using a hash. In this paper, the chunk of computing codes and the narrative writings will be referred to computational components and narrative components respectively (Kane,Jiang and Urbanek, 2020).

R markdown Statistical analysis tends to be more reachable and interpretable to public audience accompanied by the rapid rise of computing abilities. While the statistical computing threshold lowers with the invention of R language, the needs to integrate computationally derived objects with narrative explanations arise. The usage of R markdown centralizes different data types with a specific format, further process with the technical work in a computationally organized way. Usually in most data analysing tasks, the first thing is data cleaning and tidying. However, this processes usually requires other environments and configuration to manipulate. Such steps have different needs in computational purpose than report or presentations. It may not become fully shown using R code or other languages natively supported by R, but authors often use narrative texts to describe the associate processes. These narrative texts can be fully embedded in the R markdown file for readers to follow without opening other documents.

Before a highly informative presentation, multiple explanatory analyses are often carried out. These explanatory analyses contain numerous amounts of table, plots and graphs, most of them have comments and notes. R markdown can save the robust components and generate documents without spending time on layouts and formats.

The advantage of R markdown’s narrative feature can be demonstrated in multiple prospects. Firstly, R markdown is as its names implies, a Markdown mark-up language of R. By using combinations of codes and embedding symbols to control the formatting and layout of a R object file, users gets the desired final output document. All of these are easy to achieve without extensive skills in coding and consumes less time and effort to learn. Packages such as “bookdown” (Xie, 2016) demonstrates the easiness for users indenting to edit long narrative components in contrast of using another commonly-used markup language – Latex. While latex may be more expressive in terms of proficiency in terms of academical writing, the coding alike syntax required to produce documents takes a substantial amount of time and effort to learn and is relatively more complicated than R markdown’s syntax.

On the other hand, statistical reports and presentations often contains numerous computational and narrative components. R markdown supports multiple file formats once a R object is completed and read for publishing. The function in R markdown for this objective is called “knit”. The process includes running all computational components, then formats the outputs along with the narrative components.

Each computational component starts with {}, with the language name between the curly brackets and ends with. During the knitting process, computation components along with their results are laid out precedingly. Each narrative component, which is so called ordinary text with out code is combined within the computational components, resulting in a desired file.

The final result is also customizable not only as in pdf or HTML format, but also includes editable formats such as Microsoft word documents. This conforms with the intention for a typical statistical report or presentation, that is, to make audience understand statistics with less to no statistical knowledge (Baumer, Cetinkaya-Rundel, Bray, Loi, and Horton, 2014). R markdown fulfils this concept by offering modifiable documents for collaborators and other users to develop narrative components based on the statistical analysis results generated beforehand.

While PDF and Word formats are commonly used by researchers in the fields for their formatting specification, they do not provide a pragmatical solution for interactive plots and graphics. Compared to static graphics, interactive graphics are extremely powerful for explanatory analysis, and complements the visualization prospect of statistical visualizations (Theus & Urbanek, 2008). Interactive graphics not only enhances the overall aesthetics of a visualization component, but could also reveal un-spotted insights. The findings may change conclusions and affect the narrative components, further changing the conclusion of a work (Healy,2018). Moreover, interactive visualization potentially provides a solution to readers with visual perception diseases such as color blindness (Wilke,2019). HTML, another format producible by R markdown, is often underestimated in its ability for interactive visualization and animations. R has a variety of packages that supports interactive widgets which can by knitted and shown on HTML webpages. Despite the numerous packages and functions supported by R to create an interactive visualization, most of them requires an increase of workload in the computational components. A optimal solution of merging computational components that produce interactive graphics and the associated narrative components can be achieved by using the R list down package (Kane,Jiang and Urbanek, 2020). This paper will demonstrate firstly, workflow on how the listdown package generates documents. This is a background summoning the previous work done by the package’s developers (Kane,Jiang and Urbanek, 2020). Chapter 3 uses example to show how the interactive graphics can be implemented into HTML using package Listdown’s decorator function.

Background

Lets suppose the data analyzing part and all coding work has completed. The results of the analysis containing summary tables, data tables and plots which we referred to computational components, are collected into a list of objects. They are roughly in the order of which we would like to present them, the next thing is to present the components in a document like html. This is a typical order of a data analyzing work processes, but it is not definite.

Sometimes, the computational components along with the results they produce are stored in multiple locations, or in many cases, on different machines. It is particularly important to centralize them. There are many advantages turning them in lists. Firstly, turning them into list of elements naturally provides a hierarchical structure for centralizing. Secondly, for most data, even on large scales, the actual presented contents are relatively small. Storing them into lists allows easier access and aligns with the concepts of centering. Last but not least, if the elements in the list are not in the order of a presentation desired, or changes accordingly, manipulating the order is much more convenient than non-centralized components.

R Listdown Nonetheless, the data cleaning and other processes iteratively repeats each time generating documents for presentation whenever knitr is used in a R markdown file. A R markdown file usually lacks semantic structure. When all computational components and narrative components are stored in one single file manually paragraphed by the author, extracting and editing components partially in a R markdown file often leads to increase of workloads after the changes are committed. In addition, R markdown does not hold any data dedicated for the file itself. In order for a computational component in R markdown that reads in the data to work, the data set has to be stored or set to a pathway specifying the location of the data, depending on either it is saved locally or on a server. To overcome the above mentioned aspects, package listdown (Kane,Jiang and Urbanek, 2020) was introduced providing functions to programmatically create R markdown files from named lists. By using functions from the package, the components can be turned into a single named list, organized in a hierarchical structure. The contents of each list denoted, including the name and type of R object can be viewed in dendrograms. On top of the lists, decorators and other customizable functions can be added to assist the problem of visualizing. This is particular useful when large datasets are added to its corresponding computational component list and the author intends to present them. Large data sets requires a substantial amount of space to be fully shown.

During a statistical analysis, the analytical process and results can be seen as two parts which can be stored separately. If the results contain graphs and plots, they could be further stored in single named lists. As everything is organized in named lists, the package has several advantages compared to normal R markdown files containing all computational and narrative components. The first is it allows multiple pathways working in parallel from the same data. When the experiment and objective is different based on the same data, computational components are expected to be different. This will affect the narrative components such as conclusions and discussions, but the data and other process remains constant. Since the different “pathways” can be stored into different lists, listdown package allows users to selectively pick the reproducible lists along with the narrative components. Normal R markdown files shows the experiment in a serial way if different experiments are stored in the same file, or users will have to open two R markdown files with the same computational component for processing in both R markdown files.

Another advantage for storing objects in a list is its capability to avoid repetitive work when data analysis updates. This is partially useful when data analysis process is updated frequently while the data source remains in the same format and standard. Once the computational components for data cleaning and process are constructed and stored into the list, the analysis may change the outputs, such as results and plots. Further changing the narrative components. However, updating analysis methods does not mean deprecating the previous methods, listdown package allows different methods to be stored and reproducible at anytime with a single knitr, this vastly improves efficiency and drops tedious repetitive works while maintaining the objectives desired. Some useful areas of statistical analysis benefiting from the listdown package are mainly but not limited to it’s usage in clinical trial data (Kane,Jiang and Urbanek, 2020).

The Rlistdown package highly integrates a bundle of computational components into a list of objects. However, when it comes to visualization components (ie. trelliscope), the plot is fixed to a specific given data. Our goal is to make it live and interactive. That is, when the author inputs different data, the plot changes correspondingly.

The data regions from the COVID-regions-2021.csv file( World Health Organization 2021) is used in this first example. The data set contains some key information of the current world spreading disease Covid-19. The number of new cases and new deaths are groupped by WHO regions in the order of date reported from 2020-01-03 to 2020-06-17. Two plots produced using ggplot2 were saved in the markdown file named computational_components_covid as lists. They are named “Case by region” and “Cases against Death”, each contains their corresponding graphics. After assessing the class of the R object comp_covid, that is, a list, the next step is to create a listdown object.

library(ggplot2)
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.0.4
## -- Attaching packages --------------------------------------- tidyverse 1.3.0 --
## v tibble  3.1.0     v purrr   0.3.4
## v tidyr   1.1.3     v stringr 1.4.0
## v readr   1.4.0     v forcats 0.5.1
## Warning: package 'tibble' was built under R version 4.0.4
## Warning: package 'tidyr' was built under R version 4.0.4
## Warning: package 'readr' was built under R version 4.0.4
## Warning: package 'purrr' was built under R version 4.0.4
## Warning: package 'stringr' was built under R version 4.0.4
## Warning: package 'forcats' was built under R version 4.0.4
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x purrr::compose() masks flextable::compose()
## x plotly::filter() masks dplyr::filter(), stats::filter()
## x dplyr::lag()     masks stats::lag()
library(scales)
## Warning: package 'scales' was built under R version 4.0.4
## 
## Attaching package: 'scales'
## The following object is masked from 'package:purrr':
## 
##     discard
## The following object is masked from 'package:readr':
## 
##     col_factor
# Load the regions data set.
regions = read.csv("COVID-regions-2021.csv", 
                    colClasses=c("character", "Date", rep("numeric", 2)))

# Creating the computational components
computational_components_covid <- list( 
  Data = regions,
`Case by region` = ggplot(regions, aes(x = Date_reported, y = New_cases, col = WHO_region, fill = WHO_region)) + 
  geom_area() + facet_wrap(.~WHO_region) + labs(title = "Number of daily COVID cases by WHO region") + scale_y_continuous(expand = rep(0,2),labels = label_comma()),

`Cases against Death` = ggplot(data = regions,
       aes(x=New_cases, y=New_deaths, color = WHO_region)) + geom_point() + labs(title = "Number of COVID cases against death by WHO region")
)
         
#Save file to the disk
 saveRDS(computational_components_covid, "comp-comp_covid.rds")
 
comp_covid <- readRDS("comp-comp_covid.rds")
class(comp_covid)
## [1] "list"

Creating the document using Package Listdown

The list containing the plots is now saved as a R object named comp-comp.rds. From here, the document goes through the following steps: A listdown object will be created. The object will be loaded into the designated document with a specified way, along with the libraries and codes required for the computational component. From the regions data example, libraryggplot2, tidyverse and scales are required, they are specified and loaded together with the saved computational object. Then the author decides how the elements in the list will be presented in the document.

#Making a listdown object
library(listdown)
library(knitr)
ld_new <- listdown(load_cc_expr = readRDS("comp-comp_covid.rds"),
package = c("ggplot2", "tidyverse","scales"))

ld_new
## 
## Listdown object description
## 
##     Package(s) imported:
##  ggplot2
##  tidyverse
##  scales
## 
##     Setup expression(s) (run before packages are loaded):
##  (none)
## 
##     Initial expression(s) (run after packages are loaded):
##  (none)
## 
##     Expression to read data:
##  readRDS("comp-comp_covid.rds")
## 
##     Decorator(s):
##  (none)
## 
##     Defaut decorator:
##  identity
## 
##     Chunk option(s):
##  (none)
## 
##     Decorator chunk option(s):
##  (none)

The listdown object named ld_new is now ready to create the document. To regularize the document output in terms of formats, it is further processed with a header. The listdown package has native support in R markdown and workflowr as yml objects (Kane,Jiang and Urbanek, 2020). The header objects are part of the list in the document, and can be edited by using ld_rmarkdown_header(). By calling the document name, a glimpse of the document content is shown, the names are clearly listed out along with the type of these objects.

covidexample <- c(
 as.character(ld_rmarkdown_header("Covid plots",
author = "Leon",
 date = "2021")),
ld_make_chunks(ld_new))

covidexample
##  [1] "---"                                        
##  [2] "title: Covid plots"                         
##  [3] "author: Leon"                               
##  [4] "date: '2021'"                               
##  [5] "output: html_document"                      
##  [6] "---"                                        
##  [7] ""                                           
##  [8] "```{r}"                                     
##  [9] "library(ggplot2)"                           
## [10] "library(tidyverse)"                         
## [11] "library(scales)"                            
## [12] ""                                           
## [13] "cc_list <- readRDS(\"comp-comp_covid.rds\")"
## [14] "```"                                        
## [15] ""                                           
## [16] "# Data"                                     
## [17] ""                                           
## [18] "```{r}"                                     
## [19] "cc_list$Data"                               
## [20] "```"                                        
## [21] ""                                           
## [22] "# Case by region"                           
## [23] ""                                           
## [24] "```{r}"                                     
## [25] "cc_list$`Case by region`"                   
## [26] "```"                                        
## [27] ""                                           
## [28] "# Cases against Death"                      
## [29] ""                                           
## [30] "```{r}"                                     
## [31] "cc_list$`Cases against Death`"              
## [32] "```"

The below codes renders covidexample into a html document.

library(knitr)
# Write the document.
#   writeLines(covidexample, "covid-example.Rmd")
#   render("covid-example.Rmd",html_document())
#   system("open covid-example.html")

From the plot,

3 The Usage of Decorators

3.1 Covid Example with decorators

In the previous chapter, the complete work flow of creating a document using listdown package is demonstrated. The example is relatively simple and straight forward. Statistically, two main point of interest arises after the document is rendered and produced. After all, the plots are informative, but they are also static. This limits the overall demonstrative ability of both plots.As the data set contains information for each individual day consistently, but only the overall trends and robust numbers are shown in the first plot. More detailed information are lost as a trade-off to revealing the robust trend of new cases daily by regions. In the second plot, the scattered points also fails to give any addition information of the data, even though it had the mechanisms of doing so. The identification feature of a visualization can be greatly improved using interactive graphics (Cook, Swayne & Buja, 2007), hence the decorator control of list down could be customized for an interactive plot. The plotly package (Sievert, 2020)) provides a native support turning ggplot objects into interactive HTML widgets.

#Add in data and decorators

ld_decorator <- listdown(load_cc_expr = readRDS("comp-comp_covid.rds"),
package = c("ggplot2", "tidyverse","scales", "plotly"),
decorator = list(ggplot = ggplotly))


coviddecoratorexample <- c(
  as.character(ld_rmarkdown_header("covid-example")),
          ld_make_chunks(ld_decorator))


 # writeLines(coviddecoratorexample, "covid-decorator-example.Rmd")
 #  render("covid-decorator-example.Rmd",html_document())
 # system("open covid-decorator-example.html")

3.2 Docorators for more complicated computational compontents

Another usful technique commoonly used is animation.

#MoreComplicated example In the previous example, the ggplot contains both the plotting mechanism for the scatter plots and the actual plots stored as list type objects. In the following example, we have used another set of data from the survminer package. The original data was added into the document, and are presented in the form of data tables, that is, a type of decorator for the data.

The rld function shows a general syntax for rendering a listdown file into a html document. The header like the previous example can be added seperately.

rld <- function(ld) {
  writeLines(ld_make_chunks(ld), "doc.Rmd")
  render("doc.Rmd",html_document())
  system("open doc.html")
}

The

#survival example:
library(listdown)
library(gtsummary)
library(flextable)
library(dplyr)
library(survival)
library(survminer)
library(rmarkdown)
library(plotly)
library(ggplot2)
library(DT)

make_surv_cc <- function(trial, treat, surv_cond_chars) {
  table_1 <- trial %>%
    tbl_summary(by = all_of(treat))  %>%
    gtsummary::as_flextable()
  scs <- lapply(c("1", surv_cond_chars),
                function(sc) {
                  sprintf("Surv(ttdeath, death) ~ %s + %s", treat, sc) %>%
                    as.formula() %>%
                    surv_fit(trial) %>%
                    ggsurvplot()
                })
  
  

  
  
  names(scs) <- c("Overall", tools::toTitleCase(surv_cond_chars))
  list(`Table 1` = table_1, `Survival Plots` = scs, test = plot_ly(z=volcano, type="surface"))
}
surv_cc <- make_surv_cc(trial, treat = "trt",
                        surv_cond_chars = c("stage", "grade"))
## Warning: `as_flextable()` was deprecated in gtsummary 1.3.3.
## Please use `as_flex_table()` instead.
## The `as_flextable()` function graduated from 'Experimental' status in
## v1.3.3. The function's name was changed to avoid a name conflict with
## `flextable::as_flextable()`. If you are trying to use the function from
## {flextable}, for the time being, use the double colon notation when both
## {gtsummary} and {flextable} are loaded, e.g. `flextable::as_flextable(...)`.
ld_cc_dendro(surv_cc)
## 
## surv_cc
##   |-- Table 1
##   |  o-- object of type(s):flextable
##   |-- Survival Plots
##    |-- Overall
##    |  o-- object of type(s):ggsurvplot ggsurv list
##    |-- Stage
##    |  o-- object of type(s):ggsurvplot ggsurv list
##    o-- Grade
##       o-- object of type(s):ggsurvplot ggsurv list
##   o-- test
##      o-- object of type(s):plotly htmlwidget
saveRDS(surv_cc, "surv-cc.rds")
ld_surv <- listdown(load_cc_expr = readRDS("surv-cc.rds"),
                    package = c("gtsummary", "flextable", "DT", 
                                "ggplot2", "plotly"),
                    decorator_chunk_opts = 
                      list(gg = list(fig.width = 8,
                                     fig.height = 6)),
                    decorator = list(data.frame = datatable),
                    echo = FALSE,
                    message = FALSE,
                    warning = FALSE,
                    fig.width = 7,
                    fig.height = 4.5)
#  rld(ld_surv)

2 Trelliscopejs Example

#trelliscopejs example The decorators example has displayed the data despite the huge amount of data in the actual dataset.

Now, by using trelliscopejs package, we are trying to fit multiple interactive plots in the listdown files as objects, further displaying after rendering into html. The following example shows how trelliscope works in R.

We have used the data from package gapminder. There are 5 continents, and we plotted the Oceania one.

library(ggplot2)
library(gapminder)
head(gapminder)
## # A tibble: 6 x 6
##   country     continent  year lifeExp      pop gdpPercap
##   <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
## 1 Afghanistan Asia       1952    28.8  8425333      779.
## 2 Afghanistan Asia       1957    30.3  9240934      821.
## 3 Afghanistan Asia       1962    32.0 10267083      853.
## 4 Afghanistan Asia       1967    34.0 11537966      836.
## 5 Afghanistan Asia       1972    36.1 13079460      740.
## 6 Afghanistan Asia       1977    38.4 14880372      786.
str(gapminder)
## tibble [1,704 x 6] (S3: tbl_df/tbl/data.frame)
##  $ country  : Factor w/ 142 levels "Afghanistan",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ continent: Factor w/ 5 levels "Africa","Americas",..: 3 3 3 3 3 3 3 3 3 3 ...
##  $ year     : int [1:1704] 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ...
##  $ lifeExp  : num [1:1704] 28.8 30.3 32 34 36.1 ...
##  $ pop      : int [1:1704] 8425333 9240934 10267083 11537966 13079460 14880372 12881816 13867957 16317921 22227415 ...
##  $ gdpPercap: num [1:1704] 779 821 853 836 740 ...
summary(gapminder$continent)
##   Africa Americas     Asia   Europe  Oceania 
##      624      300      396      360       24
#just oceania 
qplot(year, lifeExp, data = subset(gapminder, continent == "Oceania")) +
  facet_wrap(~ country + continent) + theme_bw()

Too much plots if we plot it stright away, the final layout is folded, hence the trelliscopejs package allows us to search plots via interactive interface.

library(listdown)
library(gapminder)
library(trelliscopejs)
library(ggplot2)
library(tidyverse)
library(DT)
library(pdp)
## Warning: package 'pdp' was built under R version 4.0.5
## 
## Attaching package: 'pdp'
## The following object is masked from 'package:purrr':
## 
##     partial
library(rmarkdown)

# Load the gapminder data set.
#  data(gapminder)

# # Creating the computational components
# computational_components_gapminder <- list(
#   Data = gapminder,
# `life expectancy` = qplot(year, lifeExp, data = gapminder) + xlim(1948, 2011) + ylim(10, 95) + theme_bw() +
#   facet_wrap(~ country + continent) + labs(title = "life expectancy by continent"))

# #Save file to the disk
#  saveRDS(computational_components_gapminder, "comp-comp_gapminder.rds")

# ld_gapminder <- listdown(load_cc_expr = readRDS("comp-comp_gapminder.rds"),
# package = c("ggplot2","gapminder"))

# gapminderexample <- c(
#  as.character(ld_rmarkdown_header("gapminder plots",
# author = "Leon",
#  date = "2021")),
# ld_make_chunks(ld_gapminder))

 # writeLines(gapminderexample, "gapminder-example.Rmd")
 #  render("gapminder-example.Rmd",html_document())
 #  system("open gapminder-example.html")


# TrelliscopeJS

# ld_gapminder_trellis <- listdown(load_cc_expr = readRDS("comp-comp_gapminder.rds"),
# package = c("ggplot2","gapminder", "trelliscopejs", "pdp"),
# decorator = list(qplot = facet_trelliscope),
# init_expr = {
#   facet_trelliscope <- partial(qplot, facet_wrap = facet_trelliscope)
# })
#
#
# gapmindertrellisexample <- c(
#  as.character(ld_rmarkdown_header("gapminder plots with trelliscope",
# author = "Leon",
#  date = "2021")),
# ld_make_chunks(ld_gapminder_trellis))

 # writeLines(gapmindertrellisexample, "gapminder-trellis-example.Rmd")
 #  render("gapminder-trellis-example.Rmd",html_document())
 #  system("open gapminder-trellis-example.html")

  
  
#trelliscope instead of facet
# library(trelliscopejs)
# qplot(year, lifeExp, data = gapminder) +
#   xlim(1948, 2011) + ylim(10, 95) + theme_bw() +
#   facet_trelliscope(~ country + continent, nrow = 2, ncol = 7, width = 300)

same survminer data try using plotly

yrlfexp <- gapminder[sample(nrow(gapminder), 500), ]
plot_ly(yrlfexp, x = yrlfexp$year, y = yrlfexp$lifeExp, 
        text = paste("continent: ", yrlfexp$continent),
        mode = "markers", color = yrlfexp$country, 
        size = yrlfexp$lifeExp)
## No trace type specified:
##   Based on info supplied, a 'scatter' trace seems appropriate.
##   Read more about this trace type -> https://plotly.com/r/reference/#scatter
## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.

## Warning: `line.width` does not currently support multiple values.
## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors

## Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, allowed maximum for palette Set2 is 8
## Returning the palette you asked for with that many colors

#for fun

library(networkD3)
## Warning: package 'networkD3' was built under R version 4.0.4
## 
## Attaching package: 'networkD3'
## The following object is masked from 'package:DT':
## 
##     JS
data(MisLinks, MisNodes)
forceNetwork(Links = MisLinks, Nodes = MisNodes, Source = "source",
             Target = "target", Value = "value", NodeID = "name",
             Group = "group", opacity = 0.4)